<!--
 * @name video
 * @description 仲裁录像页面
 * @author idouya
 * @email elegentfrog@163.com
 * @date 2025-05-16
 -->

<template>
  <div class="p-video">
    <PageTop title="Fencing Video System Action" showIcon @gotoUrl="gotoUrl('home')" />
    <div class="video-center">
      <div class="left">
        <div class="title">比赛场次</div>
        <div class="content" @mouseenter="enableHotkeys('duel')" @mouseleave="disableHotkeys">
          <div
            :class="['content-item', selected.duel === item.id ? 'selected' : 'default']"
            @click="changeDuel(item)"
            v-for="(item, index) in duelList"
            :key="index"
          >
            {{ item.name }}
          </div>
        </div>
      </div>
      <div class="center">
        <div :class="[videoNum === 1 ? 'live-text' : 'record-text']">
          <div class="blinking-dot"></div>
          {{ videoNum === 1 ? '直播中' : '点播中' }}
        </div>
        <!-- <video
          id="liveVideo"
          ref="livePlayer"
          muted
          autoplay
          playsinline
          controls
          class="live"
          v-show="videoNum === 1"
        ></video> -->
        <video
          ref="recordPlayer"
          @ended="onRecordEnd"
          muted
          autoplay
          controls
          class="record"
        >
          您的浏览器不支持视频播放。
        </video>
      </div>
      <div class="right">
        <div class="title">
          <div>动作片段（打点）</div>
          <div class="back-live" @click="backLive">返回直播</div>
        </div>
        <div class="content" @mouseenter="enableHotkeys('point')" @mouseleave="disableHotkeys">
          <div
            :class="['content-item', selected.point === item.id ? 'selected' : 'default']"
            @click="changePoint(item)"
            v-for="(item, index) in pointList"
            :key="index"
          >
            <div>{{ item.app }} {{ item.stream }}</div>
            <div class="m3u8">{{ item.m3u8_url }}</div>
          </div>
        </div>
      </div>
    </div>
    <page-bottom title="北京盈越体育产业发展有限公司"></page-bottom>
  </div>
</template>

<script setup>
import Storage from '@/assets/js/storage'
import Utils from '@/assets/js/utils'
import PageTop from '@/components/PageTop.vue'
import PageBottom from '@/components/PageBottom.vue'
import hotkeys from 'hotkeys-js'
import Hls from 'hls.js'
import { ref } from 'vue'

const { proxy } = getCurrentInstance()
const router = useRouter()
const route = useRoute()

const vodListInterval = ref(null)

const livePlayer = ref(null)
const liveUrl = ref('http://192.168.8.104:1985/rtc/v1/whep/?app=match2&stream=live')

const sessionId = ref(null)
const videoNum = ref(1)
const videoSrc = ref('example.mp4')
const recordPlayer = ref(null)
const errorMsg = ref(null)
const srsSdk = ref(null)
const recordPlayNum = ref(1)

const selected = reactive({
  duel: 1,
  point: 2,
  m3u8_url: '',
  match: 'match1',
})

const duelList = ref([
  {
    id: 1,
    name: '成年组男子花剑个人-32表-match01 (上海) 张三 VS 刘国诚 （北京）',
    match: 'match1',
  },
  {
    id: 2,
    name: '成年组男子花剑个人-32表-match02 (上海) 张三 VS 刘国诚 （北京）',
    match: 'match2',
  },
])

const pointList = ref([])

onBeforeMount(() => {
  getVodList()
})

onMounted(() => {
  // palyLive()
  onRecordPlay()
  // onLivePlay()
  // playInterval()
  hotkeys.bind('up', keyEvent)
  hotkeys.bind('down', keyEvent)
})

onBeforeUnmount(() => {
  hotkeys.unbind('up')
  hotkeys.unbind('down')
  clearInterval(vodListInterval.value)
  vodListInterval.value = null
  if (srsSdk.value) {
    srsSdk.value.close()
    srsSdk.value = null
  }
})

const gotoUrl = (name) => {
  if (name) {
    router.push({
      name: name,
    })
  }
}

// 轮训获取点播列表
const playInterval = () => {
  vodListInterval.value = setInterval(() => {
    getVodListNoLoading()
  }, 2 * 1000)
}

// 监听热键
const enableHotkeys = (type) => {
  hotkeys('up', (e, handler) => keyEvent(e, handler, type))
  hotkeys('down', (e, handler) => keyEvent(e, handler, type))
}

// 移除热键
const disableHotkeys = () => {
  hotkeys.unbind('up')
  hotkeys.unbind('down')
}

// 触发热键事件
const keyEvent = (e, handler, type) => {
  if (type === 'duel') {
    const curIndex = duelList.value.findIndex((item) => item.id === selected.duel)
    switch (handler.key) {
      case 'up':
        if (curIndex !== 0) {
          changeDuel(duelList.value[curIndex - 1])
        }
        break
      case 'down':
        if (curIndex !== duelList.value.length - 1) {
          changeDuel(duelList.value[curIndex + 1])
        }
        break
    }
  } else if (type === 'point') {
    const curIndex = pointList.value.findIndex((item) => item.id === selected.point)
    switch (handler.key) {
      case 'up':
        if (curIndex !== 0) {
          changePoint(pointList.value[curIndex - 1])
        }
        break
      case 'down':
        if (curIndex !== pointList.value.length - 1) {
          changePoint(pointList.value[curIndex + 1])
        }
        break
    }
  }
}

// 返回播放直播流
const backLive = () => {
  if (videoNum.value !== 1) {
    if (srsSdk.value) {
      srsSdk.value.close()
      srsSdk.value = null
    }
    onLivePlay()
    videoNum.value = 1
  }
}

// 切换比赛场次
const changeDuel = (row) => {
  selected.duel = row.id
  selected.match = row.match
  onLivePlay()
  getVodList()
  videoNum.value = 1
}

// 切换点播流
const changePoint = (row) => {
  selected.point = row.id
  selected.m3u8_url = row.m3u8_url
  onRecordPlay()
  videoNum.value = 2
}

// 播放直播流
async function onLivePlay() {
  errorMsg.value = null
  sessionId.value = null

  liveUrl.value = `http://192.168.8.104:1985/rtc/v1/whep/?app=${selected.match}&stream=live`
  console.log(liveUrl.value)
  if (!liveUrl.value) {
    errorMsg.value = '请输入有效的播放地址'
    return
  }

  try {
    if (srsSdk.value) {
      srsSdk.value.close()
      srsSdk.value = null
    }

    srsSdk.value = new SrsRtcWhipWhepAsync()

    await srsSdk.value.play(liveUrl.value)

    if (livePlayer.value) {
      livePlayer.value.srcObject = srsSdk.value.stream
    }

    sessionId.value = srsSdk.value.sessionid || '无'
  } catch (e) {
    errorMsg.value = e.toString()
    if (srsSdk.value) {
      srsSdk.value.close()
      srsSdk.value = null
    }
  }
}

// 播放点播流
const onRecordPlay = () => {
  videoSrc.value = 'http://192.168.8.104:8080/ive/tm.m3u8'
  nextTick(() => {
    if (Hls.isSupported()) {
      const hls = new Hls()
      hls.loadSource(videoSrc.value)
      hls.attachMedia(recordPlayer.value)
      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        console.log('HLS loaded.')
        recordPlayer.value.currentTime = 3
        recordPlayer.value.playbackRate = 0.4
        recordPlayer.value.play()
        recordPlayNum.value = 1
      })
      hls.on(Hls.Events.ERROR, (event, data) => {
        console.error('HLS 错误事件：', data)
      })
    } else if (recordPlayer.value.canPlayType('application/vnd.apple.mpegurl')) {
      // Safari 原生支持
      recordPlayer.value.src = videoSrc.value
      recordPlayer.value.playbackRate = 0.4
    } else {
      console.error('该浏览器不支持 HLS 播放')
    }
  })
}

// 监听点播视频播放结束事件
const onRecordEnd = () => {
  if (recordPlayNum.value === 1) {
    recordPlayNum.value = 2
    recordPlayer.value.playbackRate = 0.7
    recordPlayer.value.play()
  } else if (recordPlayNum.value === 2) {
    videoNum.value = 1
    // test()
  }
}

// 轮训获取点播列表
const getVodListNoLoading = () => {
  let params = {
    app_name: selected.match,
  }
  proxy
    .$postJson('record/arbitrationVideo/api/getM3u8VodList', params)
    .then((res) => {
      pointList.value = res.data
      if (res.data.length && parseInt(Storage.get('newId')) !== res.data[0].id) {
        selected.point = res.data[0].id
        selected.m3u8_url = res.data[0].m3u8_url
        Storage.set('newId', res.data[0].id)
        Storage.set('m3u8_url', selected.m3u8_url)
        videoNum.value = 2
        onRecordPlay()
      }
    })
    .catch((err) => {
      ElMessage.error(err.msg || err)
    })
}

// 获取点播列表
const getVodList = () => {
  let params = {
    app_name: selected.match,
  }
  proxy
    .$postJson('record/arbitrationVideo/api/getM3u8VodList', params)
    .then((res) => {
      pointList.value = res.data
      if (res.data.length) {
        selected.point = res.data[0]?.id
        selected.m3u8_url = res.data[0]?.m3u8_url
        Storage.set('newId', res.data[0]?.id)
        Storage.set('m3u8_url', selected?.m3u8_url)
        // onRecordPlay()
      }
    })
    .catch((err) => {
      ElMessage.error(err.msg || err)
    })
}
</script>

<style scoped lang="scss">
@import '@/assets/scss/video/video';
</style>
